#ifndef SMARTPTR_H
#define SMARTPTR_H

#ifndef NULL
#define NULL 0
#endif

template<class T>class SmartPtr;

//SmartPtr class,using refrence count,do not support muti-threaded.
template<class T>
class SmartPtr<T*>
{
public:
	SmartPtr()
		:m_Data(NULL),m_RefCount(NULL)
	{
	}
	SmartPtr(T* val)
		:m_Data(NULL),m_RefCount(NULL)
	{
		if (val != NULL)
		{
			m_Data = val;
			m_RefCount = new unsigned int;
			*m_RefCount = 1;
		}
	}

	SmartPtr(const SmartPtr& val)
		:m_Data(val.m_Data),m_RefCount(val.m_RefCount)
	{
		if (m_RefCount!=NULL) 
		{
			(*m_RefCount)++;
		}
	}

	virtual ~SmartPtr()
	{
		release();
	}

	SmartPtr& operator=(const SmartPtr<T*>& val)
	{
		release();
		m_Data = val.m_Data;
		m_RefCount = val.m_RefCount;
		if (m_RefCount!=NULL)
		{
			(*m_RefCount)++;
		}
		return *this;
	}

	bool operator==(const SmartPtr& val)const
	{
		return m_Data == val.m_Data;
	}
	bool operator==(const T* val)const
	{
		return m_Data == val;
	}
	bool operator!=(const SmartPtr& val)const
	{
		return m_Data != val.m_Data;
	}
	bool operator!=(const T* val)const
	{
		return m_Data != val;
	}

	T* operator->()
	{
		return m_Data;
	}
	const T* operator->()const
	{
		return m_Data;
	}
	T& operator*()
	{
		return *m_Data;
	}
	const T& operator*()const
	{
		return *m_Data;
	}
	bool operator<(const SmartPtr& val)const
	{
		return m_Data < val.m_Data;
	}

	const T* ptr()const
	{
		return m_Data;
	}

	unsigned int ref_count()const
	{
		if ( m_RefCount == NULL ) return 0;
		else return *m_RefCount;
	}

	void release()
	{
		if (m_RefCount==NULL) return;
		if (--(*m_RefCount) == 0) 
		{
			delete m_Data;
			delete m_RefCount;
		}
		m_Data = NULL;
		m_RefCount = NULL;
	}

protected:
	T* m_Data;
	unsigned int * m_RefCount;

};











#endif
